﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Dynamic;
using System.Linq;
using System.Text;
using Aragorn.SOA.ORM.DapperExtensions.Mapper;
using Aragorn.SOA.ORM.DapperExtensions.Sql;
using Dapper;

namespace Aragorn.SOA.ORM.DapperExtensions
{
    public interface IDapperImplementor
    {
        ISqlGenerator SqlGenerator
        {
            get;
        }

        int Count<T>(IDbConnection connection, object predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;

        bool Delete<T>(IDbConnection connection, T entity, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;

        bool Delete<T>(IDbConnection connection, object predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;

        T Get<T>(IDbConnection connection, dynamic id, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;

        IEnumerable<T> GetList<T>(IDbConnection connection, object predicate, DbContextData contextData, IList<ISort> sort, IDbTransaction transaction, int? commandTimeout, bool buffered)
        where T : class;

        IMultipleResultReader GetMultiple(IDbConnection connection, GetMultiplePredicate predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout);

        IEnumerable<T> GetPage<T>(IDbConnection connection, object predicate, DbContextData contextData, IList<ISort> sort, int page, int resultsPerPage, IDbTransaction transaction, int? commandTimeout, bool buffered)
        where T : class;

        IEnumerable<T> GetSet<T>(IDbConnection connection, object predicate, DbContextData contextData, IList<ISort> sort, int firstResult, int maxResults, IDbTransaction transaction, int? commandTimeout, bool buffered)
        where T : class;

        void Insert<T>(IDbConnection connection, IEnumerable<T> entities, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;

        dynamic Insert<T>(IDbConnection connection, T entity, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;

        bool Update<T>(IDbConnection connection, T entity, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class;
    }

    public class DapperImplementor : IDapperImplementor
    {
        public DapperImplementor(ISqlGenerator sqlGenerator)
        {
            SqlGenerator = sqlGenerator;
        }

        public ISqlGenerator SqlGenerator { get; private set; }

        public T Get<T>(IDbConnection connection, dynamic id, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate predicate = (IPredicate)this.GetIdPredicate(map, id);
            T t = this.GetList<T>(connection, map, predicate, contextData, null, transaction, commandTimeout, true).SingleOrDefault<T>();
            return t;
        }

        //public void Insert<T>(IDbConnection connection, IEnumerable<T> entities, IDbTransaction transaction, int? commandTimeout) where T : class
        //{
        //    IClassMapper classMap = SqlGenerator.Configuration.GetMap<T>();
        //    var properties = classMap.Properties.Where(p => p.KeyType != KeyType.NotAKey);

        //    foreach (var e in entities)
        //    {
        //        foreach (var column in properties)
        //        {
        //            if (column.KeyType == KeyType.Guid)
        //            {
        //                Guid comb = SqlGenerator.Configuration.GetNextGuid();
        //                column.PropertyInfo.SetValue(e, comb, null);
        //            }
        //        }
        //    }

        //    string sql = SqlGenerator.Insert(classMap);

        //    connection.Execute(sql, entities, transaction, commandTimeout, CommandType.Text);
        //}

        //public dynamic Insert<T>(IDbConnection connection, T entity, IDbTransaction transaction, int? commandTimeout) where T : class
        //{
        //    IClassMapper classMap = SqlGenerator.Configuration.GetMap<T>();
        //    List<IPropertyMap> nonIdentityKeyProperties = classMap.Properties.Where(p => p.KeyType == KeyType.Guid || p.KeyType == KeyType.Assigned).ToList();
        //    var identityColumn = classMap.Properties.SingleOrDefault(p => p.KeyType == KeyType.Identity);
        //    foreach (var column in nonIdentityKeyProperties)
        //    {
        //        if (column.KeyType == KeyType.Guid)
        //        {
        //            Guid comb = SqlGenerator.Configuration.GetNextGuid();
        //            column.PropertyInfo.SetValue(entity, comb, null);
        //        }
        //    }

        //    IDictionary<string, object> keyValues = new ExpandoObject();
        //    string sql = SqlGenerator.Insert(classMap);
        //    if (identityColumn != null)
        //    {
        //        IEnumerable<long> result;
        //        if (SqlGenerator.SupportsMultipleStatements())
        //        {
        //            sql += SqlGenerator.Configuration.Dialect.BatchSeperator + SqlGenerator.IdentitySql(classMap);
        //            result = connection.Query<long>(sql, entity, transaction, false, commandTimeout, CommandType.Text);
        //        }
        //        else
        //        {
        //            connection.Execute(sql, entity, transaction, commandTimeout, CommandType.Text);
        //            sql = SqlGenerator.IdentitySql(classMap);
        //            result = connection.Query<long>(sql, entity, transaction, false, commandTimeout, CommandType.Text);
        //        }

        //        long identityValue = result.First();
        //        int identityInt = Convert.ToInt32(identityValue);
        //        keyValues.Add(identityColumn.Name, identityInt);
        //        identityColumn.PropertyInfo.SetValue(entity, identityInt, null);
        //    }
        //    else
        //    {
        //        connection.Execute(sql, entity, transaction, commandTimeout, CommandType.Text);
        //    }

        //    foreach (var column in nonIdentityKeyProperties)
        //    {
        //        keyValues.Add(column.Name, column.PropertyInfo.GetValue(entity, null));
        //    }

        //    if (keyValues.Count == 1)
        //    {
        //        return keyValues.First().Value;
        //    }

        //    return keyValues;
        //}

        //新增
        #region Insert新增
        public void Insert<T>(IDbConnection connection, IEnumerable<T> entities, DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IEnumerable<IPropertyMap> enumerable = from p in map.Properties
                                                   where p.KeyType != KeyType.NotAKey
                                                   select p;
            foreach (T current in entities)
            {
                foreach (IPropertyMap current2 in enumerable)
                {
                    if (current2.KeyType == KeyType.Guid)
                    {
                        Guid nextGuid = this.SqlGenerator.Configuration.GetNextGuid();
                        current2.PropertyInfo.SetValue(current, nextGuid, null);
                    }
                }
            }
            string sql = this.SqlGenerator.Insert(map);
            connection.Execute(sql, contextData, entities, transaction, commandTimeout, new CommandType?(CommandType.Text));
        }

        public dynamic Insert<T>(IDbConnection connection, T entity, DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            List<IPropertyMap> list = (from p in map.Properties
                                       where p.KeyType == KeyType.Guid || p.KeyType == KeyType.Assigned
                                       select p).ToList<IPropertyMap>();
            IPropertyMap propertyMap = map.Properties.SingleOrDefault((IPropertyMap p) => p.KeyType == KeyType.Identity);
            foreach (IPropertyMap current in list)
            {
                if (current.KeyType == KeyType.Guid)
                {
                    Guid nextGuid = this.SqlGenerator.Configuration.GetNextGuid();
                    current.PropertyInfo.SetValue(entity, nextGuid, null);
                }
            }
            IDictionary<string, object> dictionary = new ExpandoObject();
            string text = this.SqlGenerator.Insert(map);
            if (propertyMap != null)
            {
                IEnumerable<long> source;
                if (this.SqlGenerator.SupportsMultipleStatements())
                {
                    text = text + this.SqlGenerator.Configuration.Dialect.BatchSeperator + this.SqlGenerator.IdentitySql(map);
                    source = connection.Query<long>(text, contextData, entity, transaction, false, commandTimeout, new CommandType?(CommandType.Text));
                }
                else
                {
                    connection.Execute(text, contextData, entity, transaction, commandTimeout, new CommandType?(CommandType.Text));
                    text = this.SqlGenerator.IdentitySql(map);
                    source = connection.Query<long>(text, contextData, entity, transaction, false, commandTimeout, new CommandType?(CommandType.Text));
                }
                long value = source.First<long>();
                int num = Convert.ToInt32(value);
                dictionary.Add(propertyMap.Name, num);
                propertyMap.PropertyInfo.SetValue(entity, num, null);
            }
            else
            {
                connection.Execute(text, contextData, entity, transaction, commandTimeout, new CommandType?(CommandType.Text));
            }
            foreach (IPropertyMap current2 in list)
            {
                dictionary.Add(current2.Name, current2.PropertyInfo.GetValue(entity, null));
            }
            if (dictionary.Count == 1)
            {
                return dictionary.First<KeyValuePair<string, object>>().Value;
            }
            return dictionary;
        }

        #endregion


        //public bool Update<T>(IDbConnection connection, T entity, IDbTransaction transaction, int? commandTimeout) where T : class
        //{
        //    IClassMapper classMap = SqlGenerator.Configuration.GetMap<T>();
        //    IPredicate predicate = GetKeyPredicate<T>(classMap, entity);
        //    Dictionary<string, object> parameters = new Dictionary<string, object>();
        //    string sql = SqlGenerator.Update(classMap, predicate, parameters);
        //    DynamicParameters dynamicParameters = new DynamicParameters();

        //    var columns = classMap.Properties.Where(p => !(p.Ignored || p.IsReadOnly || p.KeyType == KeyType.Identity));
        //    foreach (var property in ReflectionHelper.GetObjectValues(entity).Where(property => columns.Any(c => c.Name == property.Key)))
        //    {
        //        dynamicParameters.Add(property.Key, property.Value);
        //    }

        //    foreach (var parameter in parameters)
        //    {
        //        dynamicParameters.Add(parameter.Key, parameter.Value);
        //    }

        //    return connection.Execute(sql, dynamicParameters, transaction, commandTimeout, CommandType.Text) > 0;
        //}



        public bool Update<T>(IDbConnection connection, T entity, DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate keyPredicate = this.GetKeyPredicate<T>(map, entity);
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            string sql = this.SqlGenerator.Update(map, keyPredicate, dictionary);
            DynamicParameters dynamicParameters = new DynamicParameters();
            IEnumerable<IPropertyMap> columns = from p in map.Properties
                                                where !p.Ignored && !p.IsReadOnly && p.KeyType != KeyType.Identity
                                                select p;
            foreach (KeyValuePair<string, object> current in from property in ReflectionHelper.GetObjectValues(entity)
                                                             where columns.Any((IPropertyMap c) => c.Name == property.Key)
                                                             select property)
            {
                dynamicParameters.Add(current.Key, current.Value, null, null, null, null, null);
            }
            foreach (KeyValuePair<string, object> current2 in dictionary)
            {
                dynamicParameters.Add(current2.Key, current2.Value, null, null, null, null, null);
            }
            return connection.Execute(sql, contextData, dynamicParameters, transaction, commandTimeout, new CommandType?(CommandType.Text)) > 0;
        }





        //public bool Delete<T>(IDbConnection connection, T entity,DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        //{
        //    IClassMapper classMap = SqlGenerator.Configuration.GetMap<T>();
        //    IPredicate predicate = GetKeyPredicate<T>(classMap, entity);
        //    return Delete<T>(connection, classMap, predicate, transaction, commandTimeout);
        //}

        //public bool Delete<T>(IDbConnection connection, object predicate, IDbTransaction transaction, int? commandTimeout) where T : class
        //{
        //    IClassMapper classMap = SqlGenerator.Configuration.GetMap<T>();
        //    IPredicate wherePredicate = GetPredicate(classMap, predicate);
        //    return Delete<T>(connection, classMap, wherePredicate, transaction, commandTimeout);
        //}


        public int Count<T>(IDbConnection connection, object predicate,DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            IClassMapper classMap = SqlGenerator.Configuration.GetMap<T>();
            IPredicate wherePredicate = GetPredicate(classMap, predicate);
            Dictionary<string, object> parameters = new Dictionary<string, object>();
            string sql = SqlGenerator.Count(classMap, wherePredicate, parameters);
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var parameter in parameters)
            {
                dynamicParameters.Add(parameter.Key, parameter.Value);
            }

            return (int)connection.Query(sql,contextData, dynamicParameters, transaction, false, commandTimeout, CommandType.Text).Single().Total;
        }

        public IMultipleResultReader GetMultiple(IDbConnection connection, GetMultiplePredicate predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        {
            if (this.SqlGenerator.SupportsMultipleStatements())
            {
                return this.GetMultipleByBatch(connection, predicate, contextData, transaction, commandTimeout);
            }
            return this.GetMultipleBySequence(connection, predicate, contextData, transaction, commandTimeout);
        }


        #region GetList
        public IEnumerable<T> GetList<T>(IDbConnection connection, object predicate, DbContextData contextData, IList<ISort> sort, IDbTransaction transaction, int? commandTimeout, bool buffered)
        where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate predicate1 = this.GetPredicate(map, predicate);
            return this.GetList<T>(connection, map, predicate1, contextData, sort, transaction, commandTimeout, true);
        }

        protected IEnumerable<T> GetList<T>(IDbConnection connection, IClassMapper classMap, IPredicate predicate, DbContextData contextData, IList<ISort> sort, IDbTransaction transaction, int? commandTimeout, bool buffered) where T : class
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            string sql = this.SqlGenerator.Select(classMap, predicate, sort, dictionary);
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (KeyValuePair<string, object> current in dictionary)
            {
                dynamicParameters.Add(current.Key, current.Value, null, null, null, null, null);
            }
            return connection.Query<T>(sql, contextData, dynamicParameters, transaction, buffered, commandTimeout, new CommandType?(CommandType.Text));
        }
        #endregion


        #region GetPage
        public IEnumerable<T> GetPage<T>(IDbConnection connection, object predicate, DbContextData contextData, IList<ISort> sort, int page, int resultsPerPage, IDbTransaction transaction, int? commandTimeout, bool buffered) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate predicate2 = this.GetPredicate(map, predicate);
            return this.GetPage<T>(connection, map, predicate2, contextData, sort, page, resultsPerPage, transaction, commandTimeout, buffered);
        }


        protected IEnumerable<T> GetPage<T>(IDbConnection connection, IClassMapper classMap, IPredicate predicate, DbContextData contextData, IList<ISort> sort, int page, int resultsPerPage, IDbTransaction transaction, int? commandTimeout, bool buffered) where T : class
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            string sql = this.SqlGenerator.SelectPaged(classMap, predicate, sort, page, resultsPerPage, dictionary);
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (KeyValuePair<string, object> current in dictionary)
            {
                dynamicParameters.Add(current.Key, current.Value, null, null, null, null, null);
            }
            return connection.Query<T>(sql, contextData, dynamicParameters, transaction, buffered, commandTimeout, new CommandType?(CommandType.Text));
        }
        #endregion


        #region GetSet
        public IEnumerable<T> GetSet<T>(IDbConnection connection, object predicate, DbContextData contextData, IList<ISort> sort, int firstResult, int maxResults, IDbTransaction transaction, int? commandTimeout, bool buffered) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate predicate2 = this.GetPredicate(map, predicate);
            return this.GetSet<T>(connection, map, predicate2, contextData, sort, firstResult, maxResults, transaction, commandTimeout, buffered);
        }

        protected IEnumerable<T> GetSet<T>(IDbConnection connection, IClassMapper classMap, IPredicate predicate, DbContextData contextData, IList<ISort> sort, int firstResult, int maxResults, IDbTransaction transaction, int? commandTimeout, bool buffered) where T : class
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            string sql = this.SqlGenerator.SelectSet(classMap, predicate, sort, firstResult, maxResults, dictionary);
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (KeyValuePair<string, object> current in dictionary)
            {
                dynamicParameters.Add(current.Key, current.Value, null, null, null, null, null);
            }
            return connection.Query<T>(sql, contextData, dynamicParameters, transaction, buffered, commandTimeout, new CommandType?(CommandType.Text));
        } 
        #endregion


        #region 删除Delete
        public bool Delete<T>(IDbConnection connection, T entity, DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate keyPredicate = this.GetKeyPredicate<T>(map, entity);
            return this.Delete<T>(connection, map, keyPredicate, contextData, transaction, commandTimeout);
        }


        public bool Delete<T>(IDbConnection connection, object predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            IClassMapper map = this.SqlGenerator.Configuration.GetMap<T>();
            IPredicate predicate2 = this.GetPredicate(map, predicate);
            return this.Delete<T>(connection, map, predicate2, contextData, transaction, commandTimeout);
        }


        protected bool Delete<T>(IDbConnection connection, IClassMapper classMap, IPredicate predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout) where T : class
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            string sql = this.SqlGenerator.Delete(classMap, predicate, dictionary);
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (KeyValuePair<string, object> current in dictionary)
            {
                dynamicParameters.Add(current.Key, current.Value, null, null, null, null, null);
            }
            return connection.Execute(sql, contextData, dynamicParameters, transaction, commandTimeout, new CommandType?(CommandType.Text)) > 0;
        } 
        #endregion

        protected IPredicate GetPredicate(IClassMapper classMap, object predicate)
        {
            IPredicate wherePredicate = predicate as IPredicate;
            if (wherePredicate == null && predicate != null)
            {
                wherePredicate = GetEntityPredicate(classMap, predicate);
            }

            return wherePredicate;
        }

        protected IPredicate GetIdPredicate(IClassMapper classMap, object id)
        {
            bool isSimpleType = ReflectionHelper.IsSimpleType(id.GetType());
            var keys = classMap.Properties.Where(p => p.KeyType != KeyType.NotAKey);
            IDictionary<string, object> paramValues = null;
            IList<IPredicate> predicates = new List<IPredicate>();
            if (!isSimpleType)
            {
                paramValues = ReflectionHelper.GetObjectValues(id);
            }

            foreach (var key in keys)
            {
                object value = id;
                if (!isSimpleType)
                {
                    value = paramValues[key.Name];
                }

                Type predicateType = typeof(FieldPredicate<>).MakeGenericType(classMap.EntityType);

                IFieldPredicate fieldPredicate = Activator.CreateInstance(predicateType) as IFieldPredicate;
                fieldPredicate.Not = false;
                fieldPredicate.Operator = Operator.Eq;
                fieldPredicate.PropertyName = key.Name;
                fieldPredicate.Value = value;
                predicates.Add(fieldPredicate);
            }

            return predicates.Count == 1
                       ? predicates[0]
                       : new PredicateGroup
                             {
                                 Operator = GroupOperator.And,
                                 Predicates = predicates
                             };
        }

        protected IPredicate GetKeyPredicate<T>(IClassMapper classMap, T entity) where T : class
        {
            var whereFields = classMap.Properties.Where(p => p.KeyType != KeyType.NotAKey);
            if (!whereFields.Any())
            {
                throw new ArgumentException("At least one Key column must be defined.");
            }

            IList<IPredicate> predicates = (from field in whereFields
                                            select new FieldPredicate<T>
                                                       {
                                                           Not = false,
                                                           Operator = Operator.Eq,
                                                           PropertyName = field.Name,
                                                           Value = field.PropertyInfo.GetValue(entity, null)
                                                       }).Cast<IPredicate>().ToList();

            return predicates.Count == 1
                       ? predicates[0]
                       : new PredicateGroup
                             {
                                 Operator = GroupOperator.And,
                                 Predicates = predicates
                             };
        }

        protected IPredicate GetEntityPredicate(IClassMapper classMap, object entity)
        {
            Type predicateType = typeof(FieldPredicate<>).MakeGenericType(classMap.EntityType);
            IList<IPredicate> predicates = new List<IPredicate>();
            foreach (var kvp in ReflectionHelper.GetObjectValues(entity))
            {
                IFieldPredicate fieldPredicate = Activator.CreateInstance(predicateType) as IFieldPredicate;
                fieldPredicate.Not = false;
                fieldPredicate.Operator = Operator.Eq;
                fieldPredicate.PropertyName = kvp.Key;
                fieldPredicate.Value = kvp.Value;
                predicates.Add(fieldPredicate);
            }

            return predicates.Count == 1
                       ? predicates[0]
                       : new PredicateGroup
                       {
                           Operator = GroupOperator.And,
                           Predicates = predicates
                       };
        }

        protected GridReaderResultReader GetMultipleByBatch(IDbConnection connection, GetMultiplePredicate predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            StringBuilder stringBuilder = new StringBuilder();
            foreach (GetMultiplePredicate.GetMultiplePredicateItem current in predicate.Items)
            {
                IClassMapper map = this.SqlGenerator.Configuration.GetMap(current.Type);
                IPredicate predicate2 = current.Value as IPredicate;
                if (predicate2 == null && current.Value != null)
                {
                    predicate2 = this.GetPredicate(map, current.Value);
                }
                stringBuilder.AppendLine(this.SqlGenerator.Select(map, predicate2, current.Sort, dictionary) + this.SqlGenerator.Configuration.Dialect.BatchSeperator);
            }
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (KeyValuePair<string, object> current2 in dictionary)
            {
                dynamicParameters.Add(current2.Key, current2.Value, null, null, null, null, null);
            }
            SqlMapper.GridReader reader = connection.QueryMultiple(stringBuilder.ToString(), contextData, dynamicParameters, transaction, commandTimeout, new CommandType?(CommandType.Text));
            return new GridReaderResultReader(reader);
        }

        protected SequenceReaderResultReader GetMultipleBySequence(IDbConnection connection, GetMultiplePredicate predicate, DbContextData contextData, IDbTransaction transaction, int? commandTimeout)
        {
            IList<SqlMapper.GridReader> list = new List<SqlMapper.GridReader>();
            foreach (GetMultiplePredicate.GetMultiplePredicateItem current in predicate.Items)
            {
                Dictionary<string, object> dictionary = new Dictionary<string, object>();
                IClassMapper map = this.SqlGenerator.Configuration.GetMap(current.Type);
                IPredicate predicate2 = current.Value as IPredicate;
                if (predicate2 == null && current.Value != null)
                {
                    predicate2 = this.GetPredicate(map, current.Value);
                }
                string sql = this.SqlGenerator.Select(map, predicate2, current.Sort, dictionary);
                DynamicParameters dynamicParameters = new DynamicParameters();
                foreach (KeyValuePair<string, object> current2 in dictionary)
                {
                    dynamicParameters.Add(current2.Key, current2.Value, null, null, null, null, null);
                }
                SqlMapper.GridReader item = connection.QueryMultiple(sql, contextData, dynamicParameters, transaction, commandTimeout, new CommandType?(CommandType.Text));
                list.Add(item);
            }
            return new SequenceReaderResultReader(list);
        }
    }
}
